#include <iostream>
#include <sys/types.h>
#include <functional>
#include <vector>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
// using func_t =std::function<void()>;
// vector<func_t> _cb;
// void FlushDask()
// {
//     cout<<"我是一个刷盘操作"<<endl;

// }
// void sched()
// {
//     cout<<"我是一个进程调度操作"<<endl;
// }

// void handler(int sig)
// {
//     for(auto f :_cb)
//     {
//         f();
//     }
//     (void)sig;
//     alarm(1);

// }
// //以上这一段代码其实，硬件中断用C++表达出来
// int main(int argc,char* argv[])
// {
//     _cb.emplace_back(FlushDask);
//     _cb.emplace_back(sched);
//     alarm(1);
//     signal(14,handler);
//     while(true)
//     {
//         pause();//等信号，否则暂停
//     }

//     //闹钟
//     // alarm(3);
//     // sleep(1);
//     // alarm(0);//取消闹钟
//     // while (true)
//     // {
//     //     cout<<"信号"<<endl;
//     //     sleep(1);
//     // }

//     // if(argc !=3)
//     // {
//     //     cout<<"输入错误"<<endl;
//     //     return 1;
//     // }

//     // int sig =stoi(argv[1]);
//     // pid_t pid =stoi(argv[2]);
//     // kill(pid,sig);
//     // return 0;
// }
// //实现一个kill命令
// 实验除0
// void handler(int sig)
// {
//     printf("我收到了一个八号信号");

// }
// int main()
// {
//     signal(8,handler);
//     int * p=nullptr;
//     *p=10;
//     // int a =10;
//     // int b =a/0;
//     return 0;
// }
// 验证core dump标识位
// int main()
// {
//     pid_t id = fork();
//     if (id == 0)
//     {
//         sleep(2);
//         exit(1);
//     }
//     int status = 0;
//     pid_t rid= waitpid(id,&status,0);
//     printf("exit code:%d exit signal:%d core dump:%d \n",(status>>8) & 0xff,status & 0x7f,(status>>7) & 0x1);
// }

// // 信号的相关操作 一个实验验证
// void print(sigset_t &pending)
// {
//     string s1;
//     for (int sig = 31; sig > 0; sig--)
//     {
//         if (sigismember(&pending, sig)) // 判断当前编号是否在pending里面
//         {
//             cout << "1";
//         }
//         else
//         {
//             cout << "0";
//         }
//     }
//     cout << endl;
// }
// void handler(int sig)
// {
//     cout<<"我获取到了一个信号"<<endl;
//     sigset_t pending;
//     sigpending(&pending);
//     print(pending);
//     cout<<"我获取了解除信号后的pending"<<endl;
//     sleep(2);
// }
// int main()
// {
//     sigset_t set; // 设置一个信号量
//     sigset_t oset;
//     sigemptyset(&set);                   // 然后用对应的信号量操作清空这个信号量
//     sigaddset(&set, 2);                  // 把二号信号添加到信号集里面
//     sigprocmask(SIG_BLOCK, &set, &oset); // 设置block位图
//     // 第一个参数表示想做什么，第二个表示要设置的位图，第三个表示返回的旧的位图
//     // SIG_BLCOK 表示向block位图里面追加set里面设置的
//     // SIG_UNBLCOK 表示向block位图里面取消set里面设置的
//     // SIG_SETMASK 表示block里面的位图结构都用set里面的
//     signal(2,handler);
//     int i = 0;
//     while (true)
//     {

//         sigset_t pending;
//         sigemptyset(&pending);
//         sigpending(&pending); // 获取pending信号集
//         sleep(1);
//         print(pending);
//         i++;
//         if (i == 10)
//         {
//             // 解除对二号的屏蔽
//             cout<<"解除对二号信号的屏蔽"<<endl;
//             sigprocmask(SIG_SETMASK, &oset, nullptr);
//         }
//     }

//     return 0;
// }

// sigaction的使用
// int sigaction(int signum,const struct sigaction *_Nullable restrict act, struct sigactigion *_Nullable restrict oldact);
// 第一个参数为信号的编号，第二个参数为信号执行读的方法，第三个参数为信号之前的执行方法
//   struct sigaction {
//                 void     (*sa_handler)(int);和这个
//                 void     (*sa_sigaction)(int, siginfo_t *, void *);
//                 sigset_t   sa_mask;只看这个，如果用户想额外屏蔽其他信号就可以把信号加入到这里面
//                 int        sa_flags;一般设置为0
//                 void     (*sa_restorer)(void);
//             };
// void handler (int sig)
// {
//     cout<<"我收到一个信号"<<endl;
// }

// int main()
// {
//     struct sigaction act, oact;
//     act.sa_flags = 0;
//     act.sa_handler=handler;
//     sigemptyset(&act.sa_mask);//只是在栈上开辟了空间，没有设置到内核
//     sigaction(2,&act,&oact);
//     //用sigaction，当某个信号的处理函数被调用时，内核自动将当前信号加入到信号屏蔽子字里面
//     //函数结束后恢复到原来的信号屏蔽字（siganl并没有这一步，不会恢复到之前的信号屏蔽字。）
//     //防止任何信号进行递归处理，当我们在处理一个二号信号的时候，（因为信号会一直发，如果不处理）又来一个2号信号，就会处理这个二号信号，这样就会一直处理2号信号，递归下去
//     while(true)
//     {
//         cout<<"我是一个进程"<<endl;
//         sleep(1);
//     }
//     return 0;
// }

